package com.thread;

import com.loy.entity.Message;
import com.loy.entity.MessageType;
import com.service.ManageClientThreads;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Iterator;
import java.util.Map;

/**
 * 1. 该类的对象 和 某个客户端保持通信
 */
public class ServerConnectClientThread extends Thread{

    private Socket socket;
    private String userId;


    public ServerConnectClientThread() {
    }

    public Socket getSocket() {
        return socket;
    }

    public void setSocket(Socket socket) {
        this.socket = socket;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public ServerConnectClientThread(Socket socket, String userId) {
        this.socket = socket;
        this.userId = userId;
    }

    @Override
    public void run() {
     // 可以发送或者接受客户端的消息
        while (true){
            System.out.println("夫妻端和客户端 ("+userId+") 保持通信，读取数据.......");
            try {
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                // 这里读取的对象是 message,这是因为走到这里就表示登录成功了，那么在和服务器进行通信时，发送的消息
                // 都是 message对象，所以这里读取数据后，转换成 message
                Message msg = (Message) ois.readObject();

                // 3. 判断这个message的类型，做相应的业务处理
                // 1. 获取在线用户列表
                ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                if(msg.getMesType().equals(MessageType.MESSAGE_GET_ONLINE_FRIEND)){
                    // 取出在线列表信息
                    System.out.println(msg.getSender() + "要获取在线用户列表");
                    String onlineUser = ManageClientThreads.getOnlineUser();
                    Message message2 = new Message();
                    message2.setContent(onlineUser);
                    message2.setGetter(msg.getSender());
                    message2.setMesType(MessageType.MESSAGE_RET_ONLINE_FRIEND);
                    oos.writeObject(message2);
                }else if(msg.getMesType().equals(MessageType.MESSAGE_CLIENT_EXIT)){
                    // 2.如果用户发送的消息是退出系统，那么我们需要从集合中找出该socket，然后关闭通道
                    System.out.println(msg.getSender() + "要退出了");
                    ManageClientThreads.remove(msg.getSender()); // 从集合中删除 和当前用户保持的 socket通道旁
                    socket.close();
                    // 退出线程
                    break; // 就是退出while循环

                }else if(msg.getMesType().equals(MessageType.MESSAGE_COMM_MES)){
                    // 3. 是私聊的话，
                    ServerConnectClientThread serverConnectClientThread = ManageClientThreads.getServerConnectClientThread(msg.getGetter());
                    // 得到消息接收者的socket
                    // 如果用户不在线的话，我们可以将消息保存到数据库，这样就可以实现离线留言
                    Socket socket = serverConnectClientThread.getSocket();
                    ObjectOutputStream oos2 = new ObjectOutputStream(socket.getOutputStream());
                    oos2.writeObject(msg);
                } else if(msg.getMesType().equals(MessageType.MESSAGE_TOALL_MES)){
                    // 4. 群发消息
                    // 遍历 ManageClientThreads 中所有的ServerConnectClientThread
                    // 并把消息发送给这些 ServerConnectClientThread 线程持有的socket
                    Map<String, ServerConnectClientThread> hm =
                            ManageClientThreads.getHm();
                    Iterator<String> iterator = hm.keySet().iterator();
                    while (iterator.hasNext()){
                        String onlineUserId = iterator.next().toString();
                        if(!onlineUserId.equals(msg.getSender())){
                            ServerConnectClientThread serverConnectClientThread = ManageClientThreads.getServerConnectClientThread(onlineUserId);
                            // 将消息转发
                            Socket socket = serverConnectClientThread.getSocket();
                            ObjectOutputStream oosUser = new ObjectOutputStream(socket.getOutputStream());
                            oosUser.writeObject(msg);
                        }
                    }
                } else if(msg.getMesType().equals(MessageType.MESSAGE_FILE_MES)) {
                    // 根据 getterI获取到对应的socket
                    ServerConnectClientThread serverConnectClientThread = ManageClientThreads.getServerConnectClientThread(msg.getGetter());
                    Socket socket = serverConnectClientThread.getSocket();
                    ObjectOutputStream oos3 = new ObjectOutputStream(socket.getOutputStream());
                    oos3.writeObject(msg);//将消息转发给接收方
                } else {
                    System.out.println("是其他类型的message，暂时不处理");
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
